package com.roamer.school.common.exception.enums;

import com.roamer.school.common.exception.BusinessException;
import com.roamer.school.common.exception.suppert.*;
import org.springframework.http.HttpStatus;

import java.util.Arrays;
import java.util.Objects;

/**
 * 异常枚举
 *
 * @author roamer
 * @version V1.0
 * @date 2019/1/20 20:26
 */
public enum ExceptionEnum {

    /**
     * 无效参数
     */
    PARAMETER_INVALID(ParameterInvalidException.class, HttpStatus.BAD_REQUEST, ResultCode.PARAM_IS_INVALID),

    /**
     * 数据未找到
     */
    NOT_FOUND(DataNotFoundException.class, HttpStatus.NOT_FOUND, ResultCode.RESULT_DATA_NONE),

    /**
     * 数据已存在
     */
    CONFLICT(DataConflictException.class, HttpStatus.CONFLICT, ResultCode.DATA_ALREADY_EXISTED),

    /**
     * 用户未登录
     */
    UNAUTHORIZED(UserNotLoginException.class, HttpStatus.UNAUTHORIZED, ResultCode.USER_NOT_LOGGED_IN),

    /**
     * 无访问权限
     */
    FORBIDDEN(PermissionForbiddenException.class, HttpStatus.FORBIDDEN, ResultCode.PERMISSION_NO_ACCESS),

    /**
     * 远程访问时错误
     */
    REMOTE_ACCESS_ERROR(RemoteAccessException.class, HttpStatus.INTERNAL_SERVER_ERROR,
                        ResultCode.INTERFACE_OUTER_INVOKE_ERROR),

    /**
     * 系统内部错误
     */
    INTERNAL_SERVER_ERROR(InternalServerException.class, HttpStatus.INTERNAL_SERVER_ERROR,
                          ResultCode.SYSTEM_INNER_ERROR);

    private Class<? extends BusinessException> exceptionClass;

    private final HttpStatus httpStatus;

    private final ResultCode resultCode;

    ExceptionEnum(Class<? extends BusinessException> exceptionClass, HttpStatus httpStatus, ResultCode resultCode) {
        this.exceptionClass = exceptionClass;
        this.httpStatus = httpStatus;
        this.resultCode = resultCode;
    }

    public Class<? extends BusinessException> getExceptionClass() {
        return exceptionClass;
    }

    public HttpStatus getHttpStatus() {
        return httpStatus;
    }

    public ResultCode getResultCode() {
        return resultCode;
    }

    /**
     * 是否有匹配的状态码
     *
     * @param httpStatus 状态码，详情参照{@link org.springframework.http.HttpStatus}
     *
     * @return {@code true} 状态码有对应的异常
     */
    public static boolean isSupportHttpStatus(int httpStatus) {
        return Arrays.stream(ExceptionEnum.values()).anyMatch(e -> e.httpStatus.value() == httpStatus);
    }

    /**
     * 是否有匹配的异常类型
     *
     * @param clazz 异常类型Class对象，详情参照{@link BusinessException}子类
     *
     * @return {@code true} 有对应的异常
     */
    public static boolean isSupportException(Class<? extends BusinessException> clazz) {
        if (Objects.isNull(clazz)) {
            return false;
        }
        return Arrays.stream(ExceptionEnum.values()).anyMatch(e -> e.exceptionClass.equals(clazz));
    }

    /**
     * 获取匹配的异常类型
     *
     * @param httpStatus 状态码，详情参照{@link org.springframework.http.HttpStatus}
     *
     * @return {@code ExceptionEnum} 状态码对应异常类型
     */
    public static ExceptionEnum getByHttpStatus(HttpStatus httpStatus) {
        if (Objects.isNull(httpStatus)) {
            return null;
        }
        for (ExceptionEnum exceptionEnum : ExceptionEnum.values()) {
            if (httpStatus.equals(exceptionEnum.httpStatus)) {
                return exceptionEnum;
            }
        }

        return null;
    }

    /**
     * 获取匹配的异常枚举
     *
     * @param clazz 异常类型Class对象，详情参照{@link BusinessException}子类
     *
     * @return {@code ExceptionEnum} 有对应的异常
     */
    public static ExceptionEnum getByExceptionClass(Class<? extends BusinessException> clazz) {
        if (Objects.isNull(clazz)) {
            return null;
        }
        for (ExceptionEnum exceptionEnum : ExceptionEnum.values()) {
            if (clazz.equals(exceptionEnum.exceptionClass)) {
                return exceptionEnum;
            }
        }

        return null;
    }

}
